﻿using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ImageTools;

namespace Kiva7.Controls
{
    public interface IImageSourceCache
    {
        bool ApplyFilter(ref ExtendedImage extendedImage);

        Uri CreateImageUri();

        string GetImageDirectoryName();

        string GetImagePath();

        ImageSource Source { get; set; }

        void SetOpacity();
    }

    public class ImageSourceCache
    {

        public ImageSourceCache(IImageSourceCache sourceCache)
        {
            _sourceCache = sourceCache;
        }

        private IImageSourceCache _sourceCache;
        private bool _isCached
            ;

        public void EntityChanged()
        {
            IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
            string path = _sourceCache.GetImagePath();

            if (!string.IsNullOrEmpty(path)
                && file.FileExists(path))
            {
                _isCached = true;
                try
                {
                    using (IsolatedStorageFileStream stream = file.OpenFile(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        BitmapImage bi = new BitmapImage();
                        bi.SetSource(stream);
                        _sourceCache.Source = bi;
                        _sourceCache.SetOpacity();
                    }
                }
                catch
                {
                    try
                    {
                        file.DeleteFile(path);
                    }
                    catch
                    {
                    }
                }
            }
            else
            {
                Uri uri = _sourceCache.CreateImageUri();
                if (uri != null)
                {
                    ImageSourceConverter isc = new ImageSourceConverter();
                    _isCached = false;
                    _sourceCache.Source = isc.ConvertFrom(uri) as ImageSource;
                }
            }
        }

        public void ImageOpened(object sender, RoutedEventArgs e)
        {
            if (!_isCached)
            {
                //ThreadPool.QueueUserWorkItem(
                //    new WaitCallback(
                //        (stateInfo) =>
                //            {
                                CacheImage();
                           // }));
            }
        }

        private void CacheImage()
        {
            string path = _sourceCache.GetImagePath();
            if (!string.IsNullOrEmpty(path))
            {
                string imageDirectory = _sourceCache.GetImageDirectoryName();
                IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();

                BitmapSource bms = _sourceCache.Source as BitmapSource;
                if (!file.FileExists(path)
                    &&
                    bms != null)
                {
                    try
                    {
                        WriteableBitmap wb = new WriteableBitmap(bms);

                        ExtendedImage extendedImage = wb.ToImage();

                        bool hasFilter = _sourceCache.ApplyFilter(ref extendedImage);

                        if (!file.DirectoryExists(imageDirectory))
                        {
                            file.CreateDirectory(imageDirectory);
                        }
                        using (IsolatedStorageFileStream isfs = file.CreateFile(path))
                        {
                            extendedImage.WriteToStream(isfs, path);
                        }

                        if (hasFilter)
                        {
                            using (
                                IsolatedStorageFileStream stream = file.OpenFile(path, FileMode.Open, FileAccess.Read,
                                                                                 FileShare.Read))
                            {
                                BitmapImage bi = new BitmapImage();
                                bi.SetSource(stream);
                                _sourceCache.Source = bi;
                                _sourceCache.SetOpacity();
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
    }
}
